using System;
using System.Collections.Generic;
using System.Text;
using NBusiness.CodeDom;
using NBusiness.ESharp.Compiler;
using NBusiness.CodeDom.Compiler;

namespace NBusiness.ESharp
{
    [Serializable]
    public class ESharpField : EntityField
    {
        protected internal override void Attach()
        {
            //Nothing
        }

        protected override void InitializeAssignmentLogic()
        {
            //Assign auto
            Assignments.Add(new AssignmentLogic(
                ESharpParser.Expressions.FieldAutoProperty,
                EntityElementType.FieldAutoProperty,
                new AssignmentLogicHandler(AssignAuto),
                EntityElementType.FieldDeclaration));

            //Assign id
            Assignments.Add(new AssignmentLogic(
                ESharpParser.Expressions.FieldIdProperty,
                EntityElementType.FieldIdProperty,
                new AssignmentLogicHandler(AssignId),
                EntityElementType.FieldDeclaration,
                EntityElementType.FieldAutoProperty));

            //Assign nullable
            Assignments.Add(new AssignmentLogic(
                ESharpParser.Expressions.FieldNullableProperty,
                EntityElementType.FieldNullableProperty,
                new AssignmentLogicHandler(AssignNullable),
                EntityElementType.FieldDeclaration));

            // Assign readonly
            Assignments.Add(new AssignmentLogic(
                ESharpParser.Expressions.FieldReadOnly,
                EntityElementType.FieldReadOnly,
                new AssignmentLogicHandler(AssignReadOnly),
                EntityElementType.FieldDeclaration,
                EntityElementType.FieldReadOnly,
                EntityElementType.FieldNullableProperty));

            //Assign type
            Assignments.Add(new AssignmentLogic(
                ESharpParser.Expressions.FieldTypes,
                EntityElementType.FieldType,
                new AssignmentLogicHandler(AssignType),
                EntityElementType.FieldDeclaration,
                EntityElementType.FieldNullableProperty,
                EntityElementType.FieldReadOnly,
                EntityElementType.FieldIdProperty));

            //Assign name
            Assignments.Add(new AssignmentLogic(
                ESharpParser.Expressions.Identifier,
                EntityElementType.FieldName,
                new AssignmentLogicHandler(AssignName),
                EntityElementType.FieldType));

            Assignments.Add(new AssignmentLogic(
                ESharpParser.Expressions.StatementEnd,
                EntityElementType.StatementEnd,
                PostAssignmentAction.Stop,
                EntityElementType.FieldName,
                EntityElementType.Unknown));
        }

        private void AssignName(object sender, AssignmentLogicEventArgs e)
        {
            Name = e.Elements.Peek().Value;
        }

        private void AssignType(object sender, AssignmentLogicEventArgs e)
        {
            Type = ESharpParser.GetFieldType(e.Elements.Peek().Value, IsNullable);

            if (Type == null)
                OnBuildError(new ESharpBuildError(ESharpErrorCode.ES2000, e.Elements.Peek()));
        }

        private void AssignReadOnly(object sender, AssignmentLogicEventArgs e)
        {
            IsReadOnly = true;
        }

        private void AssignNullable(object sender, AssignmentLogicEventArgs e)
        {
            IsNullable = true;
        }

        private void AssignAuto(object sender, AssignmentLogicEventArgs e)
        {
            IsAuto = true;
        }

        private void AssignId(object sender, AssignmentLogicEventArgs e)
        {
            IsId = true;
            if (IsAuto) IsReadOnly = true;
        }
    }
}
